package com.derbysoft.dswitch.adapter.ihg.dswitch3.translate.impl;

import com.derbysoft.dswitch.adapter.ihg.common.domain.RatePlan;
import com.derbysoft.dswitch.adapter.ihg.dswitch3.translate.Translator;
import com.derbysoft.dswitch.adapter.ihg.dto.OTAHotelAvailRS;
import com.derbysoft.dswitch.adapter.ihg.dto.RoomRate;
import com.derbysoft.dswitch.adapter.ihg.dto.RoomType;
import com.derbysoft.dswitch.dto.hotel.avail.*;
import com.derbysoft.dswitch.dto.hotel.common.RoomRateDTO;
import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailResponse;
import com.derbysoft.dswitch.remote.hotel.dto.HotelReservationRequest;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by: jason
 * Date: 2012-5-10
 */
@Component("hotelAvailRSTranslatorV2")
public class HotelAvailRSTranslatorV2Impl extends BaseTranslator
        implements Translator<OTAHotelAvailRS, HotelAvailResponse, HotelReservationRequest> {

    @Override
    public HotelAvailResponse translate(OTAHotelAvailRS otaHotelAvailRS, HotelReservationRequest reservationRequest) {
        HotelAvailResponse hotelAvailResponse = new HotelAvailResponse();
        hotelAvailResponse.setTaskId(reservationRequest.getHeader().getTaskId());
        hotelAvailResponse.setHotelAvailRS(createHotelAvailRS(otaHotelAvailRS, reservationRequest));
        return hotelAvailResponse;
    }

    private HotelAvailRS createHotelAvailRS(OTAHotelAvailRS otaHotelAvailRS, HotelReservationRequest request) {
        HotelAvailRS hotelAvailRS = new HotelAvailRS();
        List<HotelAvailRoomStayDTO> hotelAvailRoomStayDTOs = new ArrayList<HotelAvailRoomStayDTO>();
        hotelAvailRoomStayDTOs.add(createAvailRoomStayDTO(otaHotelAvailRS, request));
        hotelAvailRS.setHotelAvailRoomStaysList(hotelAvailRoomStayDTOs);
        if (hotelAvailRS.getHotelAvailRoomStaysList().isEmpty()) {
            ArrayList<String> noAvailHotels = new ArrayList<String>();
            noAvailHotels.add(request.getHotelReservationRQ().getHotelReservation().getHotelCode());
            hotelAvailRS.setNoAvailHotelsList(noAvailHotels);
        }
        return hotelAvailRS;
    }

    private HotelAvailRoomStayDTO createAvailRoomStayDTO(OTAHotelAvailRS otaHotelAvailRS, HotelReservationRequest request) {
        HotelAvailRoomStayDTO hotelAvailRoomStayDTO = new HotelAvailRoomStayDTO();
        hotelAvailRoomStayDTO.setHotelCode(request.getHotelReservationRQ().getHotelReservation().getHotelCode());
        hotelAvailRoomStayDTO.setRoomStaysList(createRoomStays(otaHotelAvailRS, request));
        return hotelAvailRoomStayDTO;
    }

    private List<AvailRoomStayDTO> createRoomStays(OTAHotelAvailRS otaHotelAvailRS, HotelReservationRequest request) {
        return new ArrayList<AvailRoomStayDTO>(createAvailRoomStayDTOsMap(otaHotelAvailRS, request).values());
    }

    private Map<String, AvailRoomStayDTO> createAvailRoomStayDTOsMap(OTAHotelAvailRS otaHotelAvailRS, HotelReservationRequest request) {
        Map<String, AvailRoomStayDTO> availRoomStayDTOHashMap = new HashMap<String, AvailRoomStayDTO>();
        if (otaHotelAvailRS.getRoomStays() == null
                || CollectionUtils.isEmpty(otaHotelAvailRS.getRoomStays().getRoomStay())
                || otaHotelAvailRS.getRoomStays().getRoomStay().get(0).getRoomRates() == null
                || CollectionUtils.isEmpty(otaHotelAvailRS.getRoomStays().getRoomStay().get(0).getRoomRates().getRoomRate())
                || otaHotelAvailRS.getRoomStays().getRoomStay().get(0).getRoomRates().getRoomRate().get(0).getRates() == null
                || CollectionUtils.isEmpty(otaHotelAvailRS.getRoomStays().getRoomStay().get(0).getRoomRates().getRoomRate().get(0).getRates().getRate())) {
            return availRoomStayDTOHashMap;
        }
        for (RoomRate roomRate : otaHotelAvailRS.getRoomStays().getRoomStay().get(0).getRoomRates().getRoomRate()) {
            RatePlan ratePlanMapping = ratePlanRepository.loadByCode(roomRate.getRatePlanCode());
            if (ratePlanMapping == null) {
                continue;
            }
            RoomType roomType = findRoomType(roomRate.getRoomTypeCode(), otaHotelAvailRS);
            RatePlanDTO ratePlanDTO = createRatePlanDTO(ratePlanMapping, roomRate, request);
            RoomTypeDTO roomTypeDTO = translateRoomType(roomType, roomRate);
            RoomRateDTO roomRateDTO = translateRoomRate(roomRate, otaHotelAvailRS.getRoomStays().getRoomStay().get(0).getTimeSpan());
            AvailRoomStayDTO availRoomStayDTO = new AvailRoomStayDTO();
            availRoomStayDTO.setCurrency(roomRate.getRates().getRate().get(0).getBase().getCurrencyCode());
            availRoomStayDTO.setLanguage(Translator.LANGUAGE);
            availRoomStayDTO.setQuantity(roomType.getNumberOfUnits());
            availRoomStayDTO.setRatePlan(ratePlanDTO);
            availRoomStayDTO.setRoomType(roomTypeDTO);
            availRoomStayDTO.setRoomRate(roomRateDTO);

            availRoomStayDTOHashMap.put(roomRate.getRoomTypeCode(), availRoomStayDTO);
        }
        return availRoomStayDTOHashMap;
    }
}
